package cn.miju.dict.translate;

import cn.hutool.core.collection.CollUtil;
import cn.miju.dict.constant.DictConstant;
import cn.miju.dict.model.DictItem;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <pre>
 * 业务类
 * </pre>
 *
 * @author zhuming
 * @version 1.0.0
 * @since 2023-05-31 15:24
 */
public class DictTranslateSerializer extends StdSerializer<Object> implements ContextualSerializer {
    /**
     * 字典名
     */
    private String name;

    private final StringRedisTemplate redisTemplate;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public DictTranslateSerializer(StringRedisTemplate redisTemplate) {
        super(Object.class);
        this.redisTemplate = redisTemplate;
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        DictTranslate annotation = property.getAnnotation(DictTranslate.class);
        return this.createContextual(annotation.name());
    }

    private JsonSerializer<?> createContextual(String name) {
        DictTranslateSerializer serializer = new DictTranslateSerializer(redisTemplate);
         serializer.setName(name);
         return serializer;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (Objects.isNull(value)) {
            return;
        }
        gen.writeObject(value);
        String dictKey = DictConstant.Redis.DICT_LIST_KEY + name;
        if (Boolean.TRUE.equals(redisTemplate.hasKey(dictKey))) {
            String dictJsonStr = redisTemplate.opsForValue().get(dictKey);
            List<DictItem> dictItemList = JSON.parseArray(dictJsonStr, DictItem.class);
            Map<String, String> dictValueMap = Maps.newHashMap();
            if (CollUtil.isNotEmpty(dictItemList)) {
                dictValueMap.putAll(dictItemList.stream().collect(Collectors.toMap(DictItem::getValue, DictItem::getLabel)));
            }
            gen.writeFieldName(gen.getOutputContext().getCurrentName() + DictConstant.DICT_TEXT_SUFFIX);
            gen.writeObject(dictValueMap.getOrDefault(value.toString(), value.toString()));
        }
    }
}
